﻿using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.Linq;
using System.Web;

namespace Medianamik.Service.ActiveDirectory.DTO
{
    public class LDAPDomainUser : IDomainUser
    {
        private readonly DirectoryEntry _userData;
        private string _firstName;
        private string _lastName;
        private string _username;
        private string _email;

        public LDAPDomainUser(DirectoryEntry userData)
        {
            _userData = userData;
        }

        public string UserName
        {
            get
            {
                if (String.IsNullOrEmpty(_username) && _userData != null)
                    _username = _userData.Properties["sAMAccountName"][0].ToString() ?? "";

                return _username;
            }
            set { _username = value; }
        }

        public string FirstName
        {
            get
            {
                if (String.IsNullOrEmpty(_firstName) && _userData != null)
                    _firstName = _userData.Properties["givenName"][0].ToString() ?? "";
                
                return _firstName;
            }
            set { _firstName = value; }
        }

        public string LastName
        {
            get
            {
                if (String.IsNullOrEmpty(_lastName) && _userData != null)
                    _lastName = _userData.Properties["sn"][0].ToString() ?? "";
                
                return _lastName;
            }
            set { _lastName = value; }
        }

        public string FullName
        {
            get
            {
               return String.Format("{0} {1}", FirstName, LastName).Trim();
            }
        }

        public string Email
        {
            get
            {
                if (String.IsNullOrEmpty(_email) && _userData != null)
                    _email = _userData.Properties["mail"][0].ToString() ?? "";

                return _email;
            }
            set { _email = value; }
        }

        private IEnumerable<string> _groups;
        public IEnumerable<string> Groups
        {
            get
            {
                if (_groups == null && _userData != null)
                {
                    List<string> rawGroups;
                    object groups = _userData.Properties["memberOf"].Value;
                    var userGroups = new List<string>();

                    if (groups is string)
                        rawGroups = new List<string> { groups.ToString() };
                    else
                        rawGroups = new List<string>(((object[])_userData.Properties["memberOf"].Value).Cast<string>());

                    rawGroups.ForEach(group => userGroups.Add(GetGroupNameFromRawGroup(group)));

                    _groups = userGroups;
                }

                return _groups;
            }
        }

        private string GetGroupNameFromRawGroup(string rawGroup)
        {
            var groupParts = rawGroup.Split(',');
            var cnPart = groupParts.Where(part => part.StartsWith("CN=")).Select(part => part.Substring(3));

            return cnPart.FirstOrDefault();
        }
    }

    public interface IDomainUser
    {
        string UserName { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
        string FullName { get; }
        string Email { get; set; }
        IEnumerable<string> Groups { get; }
    }
}
